home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
121_01
/
fseek.c
< prev
next >
Wrap
Text File
|
1985-08-19
|
4KB
|
130 lines
/*
HEADER: CUG 121.??;
TITLE: fseek - routines for more.c;
VERSION: 1.0;
DATE: 08/01/85;
DESCRIPTION: "This module provides two functions: (1) fseek - seek to
a character position in file, and (2) ftell - says where
in file you are. These provide Unix-like facilities for
character seek & positional query to BDS C programs.";
KEYWORDS: buffered, seek;
SYSTEM: CP/M;
FILENAME: FSEEK.C;
AUTHORS: Mike W. Meyer;
COMPILERS: BDS-C 1.50;
*/
/*
* fseek.c - subroutines to provide Unix-like facilities for BDS C
*
* Description
* This module provides two functions:
* fseek - seek to character position in file
* ftell - says where in file you are
*
*
* fseek - a character seek for the BDS C buffered I/O routines
*
* This routine is used by more.c. It provides a Unix-like character
* seek for BDS C. Arguments -
* f - the I/O Buffer pointer
* tosec - an int saying where we want to be
* code - Tells how to interpret tosec:
* code = 0) absolute, characters
* code = 1) relative, characters
* code = 2) * from end, characters
* code = 3) absolute, sectors
* code = 4) relative, sectors
* code = 5) * from end, sectors
* * - not implemented, but there to model the
* Unix V6 seek call.
* mwm 2/81
*/
#include <bdscio.h>
fseek(f, tosec, code)
struct _buf *f;
{
int bchar, cchar, tochar;
unsigned bsec, csec, wsec;
/*
* The variable names -
* bX is the buffer length, in X's.
* Xchar is a character offset in a sector.
* Xsec is a sector offset in the file.
* toX is where we want to go to.
* wsec is the next sector to be read.
* cX is where we are.
*/
/* extract some info about the buffer */
bsec = (bchar = f -> _nextp - f -> _buff + f -> _nleft) / SECSIZ;
/* now, find out where we are */
if ((wsec = tell(f -> _fd)) == ERROR)
return(ERROR);
cchar = bchar - f -> _nleft;
csec = wsec - bsec + cchar / SECSIZ;
cchar %= SECSIZ;
/* Next, where do we want to be */
if (code > 2) { /* by sectors, the easy part */
tochar = cchar;
if (code == 4)
/* don't seek past 0 */
if (tosec < 0 && abs(tosec) > csec)
tochar = tosec = 0;
else tosec += csec;
else if (code != 3)
return(ERROR);
}
else { /* by characters. Hard */
tochar = tosec % SECSIZ;
tosec /= SECSIZ;
if (code == 1) {
tochar += cchar;
tosec += tochar / SECSIZ;
tochar %= SECSIZ;
if (tosec < 0 && abs(tosec) > csec)
tochar = tosec = 0;
else tosec += csec;
}
else if (code != 0)
return(ERROR);
}
/* Now go there! */
if (tosec < wsec && tosec > wsec - bsec) {
/* in the buffer, just rearrange things */
tochar += (bsec - (wsec - tosec)) * SECSIZ;
f -> _nleft = bchar - tochar;
f -> _nextp = f -> _buff + tochar;
return(OK);
}
/* Not in the buffer, so set the I/O pointer,
and then rearrange the buffer */
if (seek(f -> _fd, tosec, 0) == ERROR)
return(ERROR);
f -> _nleft = 0;
getc(f); /* force the buffer to be filled */
f -> _nextp = f -> _buff + tochar;
f -> _nleft++;
f -> _nleft -= tochar;
return(OK);
}
/*
* ftell - a tell for BDS C buffered I/O
*
* Argument -
* file - the I/O Buffer pointer
*/
unsigned ftell(file)
struct _buf *file;
{
unsigned wsec, bsec, csec;
if ((wsec = tell(file -> _fd)) == ERROR)
return(ERROR);
return(SECSIZ * wsec - file -> _nleft);
}